package cn.tedu.knows.faq.service.impl;

import cn.tedu.knows.commons.exception.ServiceException;
import cn.tedu.knows.commons.model.*;
import cn.tedu.knows.faq.kafka.KafkaProducer;
import cn.tedu.knows.faq.mapper.QuestionMapper;
import cn.tedu.knows.faq.mapper.QuestionTagMapper;
import cn.tedu.knows.faq.mapper.UserQuestionMapper;
import cn.tedu.knows.faq.service.IQuestionService;
import cn.tedu.knows.faq.service.ITagService;
import cn.tedu.knows.faq.vo.QuestionVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author tedu.cn
 * @since 2021-07-23
 */
@Service
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> implements IQuestionService {

    @Autowired
    private QuestionMapper questionMapper;
    @Autowired
    private ITagService tagService;


    @Override
    public PageInfo<Question> getMyQuestion(String username,
                                            Integer pageNum, Integer pageSize) {
        //1.根据用户名查询用户信息
        User user=getUser(username);
        if(user == null){
            throw new ServiceException("用户不存在");
        }
        //2.根据用户id查询用户的所有问题
        QueryWrapper<Question> query=new QueryWrapper<>();
        //设定条件 :1 user_id必须是当前登录用户的id
        query.eq("user_id",user.getId());
        //         2 查询出的问题不能是被删除的
        query.eq("delete_status",0);
        //         设置创建时间降序排序
        query.orderByDesc("createtime");
        //执行分页查询的指令
        //PageHelper实现分页的原理是在下次查询操作时,
        // 对sql语句末尾添加limit关键字
        PageHelper.startPage(pageNum,pageSize);
        List<Question> list=questionMapper.selectList(query);
        //遍历list中所有问题,为每个问题的标签集合赋值
        for(Question question: list){
            List<Tag> tags=tagName2Tags(question.getTagNames());
            question.setTags(tags);
        }
        //3.返回
        return new PageInfo<>(list);
    }


    //编写专门处理标签名称字符串转换为List<Tag>的方法
    private List<Tag> tagName2Tags(String tagNames){
        //tagNames:"Java基础,Java SE,面试题"
        String[] names=tagNames.split(",");
        //names:{"Java基础","Java SE","面试题"}
        //声明接收对应标签的list
        List<Tag> tags=new ArrayList<>();
        //包含所有标签的map
        Map<String,Tag> tagMap=tagService.getTagMap();
        //遍历names数组将数组元素对应的tag对象保存到tags集合中
        for(String key:names){
            tags.add(tagMap.get(key));
        }
        return tags;
    }

    @Autowired
    private QuestionTagMapper questionTagMapper;
    @Autowired
    private UserQuestionMapper userQuestionMapper;

    @Autowired
    private KafkaProducer kafkaProducer;

    @Override
    //@Transactional功能,保证当前方法中
    // 所有数据库操作要么都执行,要么都不执行
    // 如果没有发生异常,就都执行,如果任何位置发生了任何异常,就都不执行
    // 如果发生异常时已经有数据库操作完成了,这个操作会自动取消(回滚)
    // 使用时机:业务逻辑层方法
    // 如果方法中有增删改方法,尤其是两次或以上的增删改操作时
    @Transactional
    public void saveQuestion(QuestionVo questionVo, String username) {
        //1.根据用户名获得用户信息
        User user=getUser(username);
        //2.将用户选中的标签拼接为字符串
        StringBuilder builder=new StringBuilder();
        for(String tagName:questionVo.getTagNames()){
            builder.append(tagName).append(",");
        }
        //builder:"java基础,javaSE,面试题"
        //abcdefgh,
        //012345678
        String tagNames=builder
                .deleteCharAt(builder.length()-1).toString();
        //3.构建Question对象
        Question question=new Question()
                .setTitle(questionVo.getTitle())
                .setContent(questionVo.getContent())
                .setUserNickName(user.getNickname())
                .setUserId(user.getId())
                .setCreatetime(LocalDateTime.now())
                .setTagNames(tagNames)
                .setStatus(0)
                .setPageViews(0)
                .setDeleteStatus(0)
                .setPublicStatus(0);
        //4.执行新增
        int num=questionMapper.insert(question);
        if(num!=1){
            throw new ServiceException("数据库异常");
        }
        //5.执行和标签关系表的新增
        //先获得包含所有标签对象的map
        Map<String,Tag> tagMap= tagService.getTagMap();
        for(String tagName:questionVo.getTagNames()){
            //根据标签名称获得标签对象
            Tag t=tagMap.get(tagName);
            QuestionTag questionTag=new QuestionTag()
                    .setQuestionId(question.getId())
                    .setTagId(t.getId());
            num=questionTagMapper.insert(questionTag);
            if(num!=1){
                throw new ServiceException("数据库异常");
            }
        }
        //6.执行和用户表(讲师)关系的新增
        //先获得包含所有讲师的map
        Map<String,User> teacherMap=new HashMap<>();
        String url="http://sys-service/v1/users/master";
        User[] users=restTemplate.getForObject(
                                    url,User[].class);
        //将查询到的所有讲师遍历保存到数组中
        for(User u:users){
            teacherMap.put(u.getNickname(),u);
        }
        for(String nickName : questionVo.getTeacherNames()){
            //根据昵称获得讲师对象
            User teacher=teacherMap.get(nickName);
            UserQuestion userQuestion=new UserQuestion()
                    .setQuestionId(question.getId())
                    .setUserId(teacher.getId())
                    .setCreatetime(LocalDateTime.now());
            num=userQuestionMapper.insert(userQuestion);
            if(num!=1){
                throw new ServiceException("数据库异常");
            }
        }
        //将新增到数据库的question对象发送到kafka以同步到ES
        kafkaProducer.sendQuestion(question);

    }

    @Override
    public Integer countQuestionsByUserId(Integer userId) {
        QueryWrapper<Question> query=new QueryWrapper<>();
        query.eq("user_id",userId);
        query.eq("delete_status",0);
        Integer count=questionMapper.selectCount(query);
        // 别忘了返回!!!!!!
        return count;
    }

    @Override
    public PageInfo<Question> getTeacherQuestions(String username, Integer pageNum, Integer pageSize) {
        User user=getUser(username);
        PageHelper.startPage(pageNum,pageSize);
        List<Question> questions=
                questionMapper.findTeacherQuestions(user.getId());
        //根据Question对象的tagNames属性获得问题列表中所有问题的标签集合
        for(Question question:questions) {
            List<Tag> tags=tagName2Tags(question.getTagNames());
            question.setTags(tags);
        }
        //别忘了返回!!!
        return new PageInfo<>(questions);
    }

    @Override
    public Question getQuestionById(Integer id) {
        //按id查询问题对象
        Question question=questionMapper.selectById(id);
        List<Tag> tags=tagName2Tags(question.getTagNames());
        question.setTags(tags);
        //别忘了返回
        return question;
    }

    @Autowired
    private RestTemplate restTemplate;
    //根据用户名获得用户的方法(Ribbon调用Sys)
    public User getUser(String username){
        String url=
           "http://sys-service/v1/auth/user?username={1}";
        User user=restTemplate.getForObject(
                url,User.class,username);
        return user;
    }

    @Override
    public PageInfo<Question> getQuestions(Integer pageNum, Integer pageSize) {
        //设置查询的页码
        PageHelper.startPage(pageNum,pageSize);
        List<Question> list=questionMapper
                        .selectList(null);
        return new PageInfo<>(list);
    }




}
